/*
 * ResourceCollection.cpp
 *
 *  Created on: Jun 8, 2010
 *      Author: Ry
 */

#include <iostream>

#include "ResourceCollection.h"
#include "mesh/DwarfMeshLoader.h"
#include "mesh/OBJMeshLoader.h"
#include "exceptions.h"

using namespace std;

ResourceCollection::ResourceCollection() {
	// Create a default material
	Material *defaultMaterial = newMaterial();
	defaultMaterial->setName("default");
	defaultMaterial->setAmbient(0.5f);
	defaultMaterial->setDiffuse(RGBA(0.5f, 0.5f, 0.5f, 1.0f));
	defaultMaterial->setSpecular(RGBA(0.5f, 0.5f, 0.5f, 1.0f));
	defaultMaterial->setShininess(96.0f);

	meshLoaders.push_back(new DwarfMeshLoader(this));
	meshLoaders.push_back(new OBJMeshLoader(this));
}

Object* ResourceCollection::newObject() {
	Object* object = new Object();
	objects.push_back(object);
	return object;
}

ShaderProgram* ResourceCollection::newShaderProgram() {
	ShaderProgram* program = new ShaderProgram();
	programs.push_back(program);
	return program;
}

Material* ResourceCollection::newMaterial() {
	Material *material = new Material;
	materials.push_back(material);
	return material;
}

void ResourceCollection::put(Material* material) {
	materials.push_back(material);
}

bool ResourceCollection::exists (Material* material) {
	for (unsigned int i = 0; i < materials.size(); i++) {
		if (materials[i] == material)
			return true;
	}
	return false;
}

Texture* ResourceCollection::loadTexture(string file, bool mipmaps) {
	Texture* texture = new Texture(file, mipmaps);
	textures.push_back(texture);
	return texture;
}

Mesh* ResourceCollection::loadMesh(string file, ShaderProgram *program) {
	for (unsigned int i = 0; i < meshLoaders.size(); i++) {
		if (meshLoaders[i]->supports(file)) {
			Mesh* mesh = meshLoaders[i]->load(file, program);
			mesh->setProgram(program);
			return mesh;
		}
	}
	throw GameException("Unsupported mesh type.");
}

void ResourceCollection::put(Mesh* mesh) {
	meshes.push_back(mesh);
}

void ResourceCollection::updateMeshes() {
	for (unsigned int i = 0; i < meshes.size(); i++) {
		meshes[i]->compile();
	}
}

void ResourceCollection::updateTextures() {
	for (unsigned int i = 0; i < textures.size(); i++) {
		textures[i]->reload();
	}
}

void ResourceCollection::rebuildShaderPrograms() {
	for (unsigned int i = 0; i < programs.size(); i++) {
		programs[i]->build();
	}
}

ResourceCollection::~ResourceCollection() {
	for (unsigned int i = 0; i < objects.size(); i++) {
		delete objects[i];
	}
	for (unsigned int i = 0; i < programs.size(); i++) {
		delete programs[i];
	}
	for (unsigned int i = 0; i < textures.size(); i++) {
		delete textures[i];
	}
	for (unsigned int i = 0; i < materials.size(); i++) {
		delete materials[i];
	}
	for (unsigned int i = 0; i < meshes.size(); i++) {
		delete meshes[i];
	}
	for (unsigned int i = 0; i < meshLoaders.size(); i++) {
		delete meshLoaders[i];
	}
}
